package com.ala4.oxcafe.boot.utils;

import cn.idev.excel.ExcelWriter;
import cn.idev.excel.FastExcelFactory;
import cn.idev.excel.converters.longconverter.LongStringConverter;
import cn.idev.excel.write.builder.ExcelWriterSheetBuilder;
import com.ala4.oxcafe.boot.ExcelExport;
import com.ala4.oxcafe.common.utils.collection.CollUtil;
import com.ala4.oxcafe.domain.R;
import com.ala4.oxcafe.export.ExportResult;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.ResponseEntity;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * excel工具类
 *
 * @author PING
 * @version 1.0.0
 * @date 2025/8/4 10:01
 */
public class ExcelUtil {

    private ExcelUtil() {
    }

    /**
     * 忽略的导出字段
     */
    public static final List<String> IGNORE_FIELDS = CollUtil.newArrayList("params", "searchValue", "delFlag");

    /**
     * 执行分页请求
     *
     * @param target
     * @param method
     * @param args
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static ExportResult<?> requestDataPage(Object target, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        // 请求数据
        Object result = method.invoke(target, args);
        ExportResult<?> data = null;
        if (result instanceof R<?> r) {
            result = r.getData();
        }
        if (result instanceof ExportResult<?> exportResult) {
            data = exportResult;
        }
        if (data == null) {
            throw new IllegalArgumentException("Response data type must be [? extends java.util.List] or ResponseEntity<? extends java.util.List>");
        }
        return data;
    }

    /**
     * 执行List请求
     *
     * @param target
     * @param method
     * @param args
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static List<?> requestDataList(Object target, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        // 请求数据
        Object result = method.invoke(target, args);
        List<?> data = null;
        if (result instanceof R<?> r) {
            result = r.getData();
        }
        if (result instanceof List) {
            data = (List<?>) result;
        } else if (result instanceof ResponseEntity<?> responseEntity) {
            if (responseEntity.getBody() instanceof List) {
                data = (List<?>) responseEntity.getBody();
            }
        }
        if (data == null) {
            String message = "Response data type must be [? extends java.util.List] or ResponseEntity<? extends java.util.List>";
            throw new IllegalArgumentException(message);
        }
        return data;
    }

    /**
     * 导出单表的excel
     *
     * @param response
     * @param excelExport
     * @return
     * @throws IOException
     */
    public static ExcelWriterSheetBuilder buildOutputExcelSingle(HttpServletResponse response, ExcelExport excelExport) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition",
                "attachment;filename*=utf-8''" + URLEncoder.encode(excelExport.excelName(), StandardCharsets.UTF_8) + ".xlsx");

        return FastExcelFactory.write(response.getOutputStream(), excelExport.value())
                .registerConverter(new LongStringConverter())
                .registerWriteHandler(CellStyleUtil.getHorizontalCellStyleStrategy())
                .excludeColumnFieldNames(ExcelUtil.IGNORE_FIELDS).sheet();
    }

    /**
     * 构建导出表对象
     *
     * @param response
     * @param excelExport
     * @return
     * @throws IOException
     */
    public static ExcelWriter buildOutputExcel(HttpServletResponse response, ExcelExport excelExport) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition",
                "attachment;filename*=utf-8''" + URLEncoder.encode(excelExport.excelName(), StandardCharsets.UTF_8) + ".xlsx");

        return buildOutputExcel(response.getOutputStream(), excelExport);
    }

    public static ExcelWriter buildOutputExcel(OutputStream outputStream, ExcelExport excelExport) {
        return FastExcelFactory.write(outputStream, excelExport.value())
                .registerConverter(new LongStringConverter())
                .registerWriteHandler(CellStyleUtil.getHorizontalCellStyleStrategy())
                .excludeColumnFieldNames(ExcelUtil.IGNORE_FIELDS).build();

    }
}
